package com.tedu.API.map;
import org.junit.Test;

import java.util.*;
import java.util.function.BiConsumer;

/**包位置：java.util.*;
 * Map顶级映射接口
 * 作用：一个元素由两个对象构成：分别健：Key与值：Value;
 *     保存一个元素：Key----value[保存一对：两个对象】
 *用途：通常与数据库搭配使用
 * 特点：健：无序、无下标、不可重复，实际存HasSet
 *      值：存泛型约束的类型，可重复，实际存Collection
 * Map 接口对象创建---实现类：
 * HasMap:【常用：HashMap的方法与Map方法类似】由健值对组成，使用哈希算法实现！
 * 健与值可以为null，健中只允许有一个null！
 * LinkedHashMap:【不常用：方法与HashMap类似】两端插入增加效率较高
 * TreeMap：【不用】【算法：红黑树】性能：效率较低，线程安全！
 * HashTable：【不用】jdk1.0版本，由哈希算法实现，解决多线程问题
 * ConcurrentHashMap：【常用】  多线程
 */
public class MapAPI {
    @Test
    public void testMap(){
        //创建Map映射集合接口
        Map<Object,String> map=new HashMap<>();
        /**
         * put(健K，值v)   返回值：V  value---实际Collection
         * 作用：映射集合存入一对元素：健与值
         */
        map.put("西游记","孙悟空");//Key健：Set集合：无序、无下标、唯一
        map.put("红楼梦","林黛玉");//Key值一致，进行覆盖
        map.put("水浒传","宋江");
        map.put("三国志","诸葛亮");
        map.put("红楼梦","贾宝玉");
        map.put(null,"无名氏");
        map.put(null,"无名氏");
        System.out.println("Map集合："+map);

        //需求：获取一组元素中值：”林黛玉“   get(健) 通过健找值
        String lin=map.get("红楼梦");
        System.out.println("通过健找值："+lin);
        //没有这个健，自动按照Collection对象，补对象默认：null
        System.out.println("通过键找值【健不存在】："+map.get("三国"));

        //删除元素中：健     remove()Key   返回值：V value  Collection
        map.remove("红楼梦");
        System.out.println("Map集合"+map);

        //size()  获取映射集合的元素个数
        System.out.println("Map集合元素总数："+map.size());

        //contains            判断健是否存在    返回值：boolean
        //containsValue()    判断值是否存在     返回值：boolean
        boolean b=map.containsKey("三国志");
        System.out.println("判断健是否存在："+b);
        boolean v=map.containsValue("宋江");
        System.out.println("判断健是否存在："+v);
    }
    /**
     * Map映射集合中：一组健值存入【一组元素：Entry】
     * 遍历映射集合：遍历所有的健、遍历所有的值，遍历所有的Entry
     * KeySet:获取集合中所有的健
     * values：获取集合中所有的值
     * entrySet：获取集合中所有的【entry：健与值】
     */
    @Test
    public void testMaps(){
        Map<Object,String> map=new HashMap<>();
        map.put("唐山","棋子烧饼");
        map.put("邢台","酸枣汁");
        map.put("邯郸","二宝烧鸡");
        map.put("沧州","火锅鸡");
        //KeySet() 获取所有的健
        Set<Object> set=map.keySet();
        //遍历所有的健：增强for
        for(Object o:set){//从set集合中获取的所有健
            System.out.println("获取的所有健："+o);
        }
        //2.values()
        Collection<String> c=map.values();
        //遍历所有的值：增强for
        for (String s:c){
            System.out.println("获取所有值:"+s);
        }
        //3.entrySet()  获取所有的Entry健值
        //返回值：Set<Map.Entry<K,V>>
        //Entry类型：Map.Entry<K,V>
        //Entry存健值的对象---Map增加一个针对“健值对”的对象
        //Map.Entry  【MAp接口.Entry对象】获取到表示所有的Entry的方法
        Set<Map.Entry<Object,String>> sets=map.entrySet();
        //获取所有【entry】健值对
        for(Map.Entry<Object,String> s:sets){
//            System.out.println("所有的entry："+s);
            //Entry中 Key 与 Value方法：getKey()  getValue()
            Object key=s.getKey();
            String value=s.getValue();
            System.out.println("打印Entry中健与值："+key+" "+value);
        }
    }
    /**
     * forEach(new BiConsumer())
     * BiConsumer 接口  ---封装Entry对象的健与值
     * 作用：遍历出集合中所有的entry【健与值】
     */
    @Test
    public void testForEach(){
        Map<Object,String> map=new HashMap<>();
        map.put("唐山","棋子烧饼");
        map.put("邢台","酸枣汁");
        map.put("邯郸","二宝烧鸡");
        map.put("沧州","火锅鸡");
        //forEach(接口)遍历映射集合：健与值
        map.forEach(new BiConsumer<Object,String>(){
            //accept(K,V)   获取Entry中所有的健与值
            public void accept(Object o, String s) {
                System.out.println("所有的健："+o);
                System.out.println("所有的值："+s);
            }
        });
    }

    /**
     * putIfAbsent()
     * 作用：存一组entry，先判断指定的键是否存在，不存在将键值插入
     *                                      存在键值不插入
     */
    @Test
    public void testHashMap(){
        Map<Object,String> map=new HashMap<>();
        map.put("唐山","棋子烧饼");
        map.put("邢台","酸枣汁");
        map.put("邯郸","二宝烧鸡");
        map.put("沧州","火锅鸡");
        map.putIfAbsent("石家庄","八大碗");
//        map.put("唐山","糖墩");
        map.putIfAbsent("唐山","麻糖");  //相同健  不插入
        System.out.println("HashMap集合："+map);
    }
}
